package com.pxst.fx.service.impl;

import cn.hutool.db.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pxst.annotations.validated.DecimalValidator;
import com.pxst.bank.entity.SysAvailableBankEntity;
import com.pxst.bank.entity.SysBankCardEntity;
import com.pxst.bank.entity.SysBankCardFlowEntity;
import com.pxst.bank.mapper.SysAvailableBankMapper;
import com.pxst.bank.mapper.SysBankCardFlowEntityMapper;
import com.pxst.bank.mapper.SysBankCardMapper;
import com.pxst.entity.BaseEntity;
import com.pxst.exception.BusinessException;
import com.pxst.exception.LoginException;
import com.pxst.exception.ParamException;
import com.pxst.fi.entity.*;
import com.pxst.fi.mapper.*;
import com.pxst.fi.resp.FiOrderResp;
import com.pxst.fx.constants.FxConstant;
import com.pxst.fx.entity.SysFxOrderChildEntity;
import com.pxst.fx.entity.SysFxOrderEntity;
import com.pxst.fx.entity.SysFxOrderExcelModel;
import com.pxst.fx.entity.SysFxOrderLogEntity;
import com.pxst.fx.mapper.SysFxOrderChildMapper;
import com.pxst.fx.mapper.SysFxOrderLogMapper;
import com.pxst.fx.req.*;
import com.pxst.fx.resp.SysFxOrderByIdChildResp;
import com.pxst.fx.resp.SysFxOrderByIdResp;
import com.pxst.fx.resp.SysFxOrderEntityResp;
import com.pxst.fx.service.SysFxOrderEntityService;
import com.pxst.fx.mapper.SysFxOrderEntityMapper;
import com.pxst.merchant.entity.SysMerchantInfo;
import com.pxst.merchant.entity.SysMerchantWalletEntity;
import com.pxst.merchant.mapper.SysMerchantInfoMapper;
import com.pxst.merchant.mapper.SysMerchantWalletMapper;
import com.pxst.resp.ApiResp;
import com.pxst.resp.PageResp;
import com.pxst.utils.AltIdUtils;
import com.pxst.utils.PageUtils;
import com.pxst.utils.SecurityFrameworkUtils;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.pxst.fi.constants.FiConstant.*;
import static com.pxst.fi.constants.FiConstant.STATUS_MANUAL_PROCESS;

/**
 * @author hy
 * @description 针对表【sys_fx_order(Settlement_下发订单)】的数据库操作Service实现
 * @createDate 2023-09-20 10:40:45
 */
@Service
public class SysFxOrderEntityServiceImpl extends JoinServiceImpl<SysFxOrderEntityMapper, SysFxOrderEntity>
        implements SysFxOrderEntityService {

    @Autowired
    private SysFxOrderEntityMapper sysFxOrderEntityMapper;

    @Autowired
    private SysFxOrderChildMapper sysFxOrderChildMapper;

    @Autowired
    private SysBankCardMapper sysBankCardMapper;

    @Autowired
    private SysBankCardFlowEntityMapper sysBankCardFlowEntityMapper;

    @Autowired
    private SysLogLastPageMapper sysLogLastPageMapper;


    @Autowired
    private SysFxOrderLogMapper sysFxOrderLogMapper;

    @Autowired
    private SysThirdPartyConfigMapper sysThirdPartyConfigMapper;

    @Autowired
    private SysThirdPartySettingMapper sysThirdPartySettingMapper;


    @Autowired
    private SysMerchantInfoMapper sysMerchantInfoMapper;

    @Autowired
    private SysMerchantWalletMapper sysMerchantWalletMapper;


    /**
     * 下发条件分页查询
     * @param sysFxOrderEntityReq
     * @return
     */
    @Override
    public ApiResp<PageResp<SysFxOrderEntityResp>> getSysFxOrderList(SysFxOrderEntityReq sysFxOrderEntityReq) {

        // 根据条件查询下发数据
        List<SysFxOrderEntityResp> list = sysFxOrderEntityMapper.getSysFxOrderList(sysFxOrderEntityReq);

        // 处理下发数据
        list.stream().map(item -> checkSysFxOrderEntityResp(item)).collect(Collectors.toList());

        return ApiResp.sucess(PageUtils.getPage(sysFxOrderEntityReq.getPage(), sysFxOrderEntityReq.getRp(), list));

    }

    /**
     * 处理下发数据
     */
    public SysFxOrderEntityResp checkSysFxOrderEntityResp(SysFxOrderEntityResp item) {
        // 根据下发Id，查询所有子下发数据
        List<SysFxOrderChildEntity> sysFxOrderChildEntities = sysFxOrderChildMapper.selectList(new LambdaQueryWrapper<SysFxOrderChildEntity>().eq(SysFxOrderChildEntity::getFxOrderMainId, item.getFxId()));

        // 有对应子下发数据，则根据子下发数据，判断下发状态
        if (sysFxOrderChildEntities != null && sysFxOrderChildEntities.size() != 0) {
            item.setStatus(getSysFxOrderStatus(sysFxOrderChildEntities));
        }
        // 下发状态等于3时，才有系统手续费，才有完成时间
        if (item.getStatus() != FxConstant.STATUS_COMPLETED) {
            item.setRate(null);
            item.setCreatedAt(null);
        }

        // 下发状态等于1，且approve_type！=1或2，approve_btn=true
        if (item.getStatus() == FxConstant.STATUS_PENDING && item.getApproveType() != 1 && item.getApproveType() != 2) {
            item.setApproveBtn(true);
        } else {
            item.setApproveBtn(false);
        }

        // 当子下发数量为0时，done_btn为false，当下发状态为2时且子下发状态不在（1，2，4）或者有一个3时 ,为true
        if (sysFxOrderChildEntities.size() != 0 && item.getStatus() == FxConstant.STATUS_PROCESSING) {
            if ((sysFxOrderChildEntities.stream().allMatch(child -> child.getStatus() != FxConstant.STATUS_PENDING && child.getStatus() != FxConstant.STATUS_PROCESSING && child.getStatus() != FxConstant.STATUS_MANUAL_PROCESS)) || sysFxOrderChildEntities.stream().anyMatch(child -> child.getStatus() == FxConstant.STATUS_COMPLETED)) {
                item.setDoneBtn(true);
            }
        } else {
            item.setDoneBtn(false);
        }

        // 下发状态为1或4，或者下发为2子下发没有数据时，reject_btn为true
        if (item.getStatus() == FxConstant.STATUS_PENDING || (item.getStatus() == FxConstant.STATUS_PROCESSING && sysFxOrderChildEntities.size() == 0) || item.getStatus() == FxConstant.STATUS_MANUAL_PROCESS) {
            item.setRejectBtn(true);
        } else {
            item.setRejectBtn(false);
        }
        // 下发状态不为2false或者子下发含有3，5，6false
        if (item.getStatus() != FxConstant.STATUS_PROCESSING || (sysFxOrderChildEntities.stream().anyMatch(child -> child.getStatus() == FxConstant.STATUS_COMPLETED || child.getStatus() == FxConstant.STATUS_FAILED || child.getStatus() == 6))) {
            item.setManualBtn(false);
        } else {
            item.setManualBtn(true);
        }
        return item;
    }


    /**
     * 汇出报表
     *
     * @param sysFxOrderEntityReq
     * @return
     */
    @Override
    public List<SysFxOrderExcelModel> download(SysFxOrderEntityReq sysFxOrderEntityReq) {
        // 查询数据
        List<SysFxOrderEntityResp> sysFxOrderList = sysFxOrderEntityMapper.getSysFxOrderList(sysFxOrderEntityReq);
        // 将数据封装Excel中
        List<SysFxOrderExcelModel> sysFxOrderExcelModelList = addDateForExcel(sysFxOrderList);
        return sysFxOrderExcelModelList;
    }

    /**
     * 下发详情
     *
     * @param id
     * @return
     */
    @Override
    public ApiResp fxOrderDetail(Long id, Integer rp) {

        Map<String, Object> map = new HashMap<>();
        // 获取下发信息
        SysFxOrderByIdResp sysFxOrderByIdResp = sysFxOrderEntityMapper.getSysFxOrderByIdResp(id);
        if (sysFxOrderByIdResp == null) {
            throw new ParamException("未找到对应下发信息", "404");
        }
        // 根据下发Id，查询所有子下发数据
        LambdaQueryWrapper<SysFxOrderChildEntity> lqw = new LambdaQueryWrapper<SysFxOrderChildEntity>().eq(SysFxOrderChildEntity::getFxOrderMainId, sysFxOrderByIdResp.getFxId());
        List<SysFxOrderChildEntity> sysFxOrderChildEntities = sysFxOrderChildMapper.selectList(lqw);

        // 有对应子下发数据，则根据子下发数据，判断下发状态
        if (sysFxOrderChildEntities != null && sysFxOrderChildEntities.size() != 0) {
            sysFxOrderByIdResp.setStatus(getSysFxOrderStatus(sysFxOrderChildEntities));
        }

        // 下发状态等于3时，才有系统手续费
        if (sysFxOrderByIdResp.getStatus() != 3) {
            sysFxOrderByIdResp.setRate(null);
        }

        // 判断AddDisplay的值
        // 下发状态不为2，AddDisplay=0
        //  排除子下发状态在(3,5,6)的数据，如果剩余的子下发数量为1且状态为4，AddDisplay=1
        if (sysFxOrderChildEntities != null && sysFxOrderChildEntities.size() != 0) {
            // 留下子下发状态为4的数据，并判断数据是否只有一条
            sysFxOrderByIdResp.setAddDisplay(
                    sysFxOrderChildEntities.stream().filter(item -> item.getStatus() == FxConstant.STATUS_MANUAL_PROCESS).count() == 1 ? 1 : 0
            );
        } else {
            sysFxOrderByIdResp.setAddDisplay(0);
        }
        map.put("FX100", sysFxOrderByIdResp);

        // 获取封装后的子下发信息
        List<SysFxOrderByIdChildResp> sysFxOrderByIdChildRespList = sysFxOrderEntityMapper.getSysFxOrderByIdChildResp(id);
        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        String finalUserName = userName;
        sysFxOrderByIdChildRespList.stream().map(i -> {
            // tpi>0，TpiDriver才会有值,否则为null
            if (i.getTpiId() == null || i.getTpiId() <= 0) {
                i.setTpiDriver(null);
            }

            // 设置CheckButton的值
            List<SysFxOrderLogEntity> sysFxOrderLogEntities = sysFxOrderLogMapper.selectList(
                    new LambdaQueryWrapper<SysFxOrderLogEntity>().eq(SysFxOrderLogEntity::getFxOrderChildId, i.getFxChildId()));
            i.setCheckButton(getCheckButtonStatus(sysFxOrderLogEntities, sysFxOrderByIdResp, i, finalUserName));

            //  设置RetryButton的值： true false
            i.setRetryButton(getRetryButtonStatus(sysFxOrderLogEntities, sysFxOrderByIdResp, i, finalUserName));

            // 设置IsRunMon的值
            i.setIsRunMon(getIsRunMonStatus(i));

            // 设置isErrUrl的值
            Integer integer = sysLogLastPageMapper.selectCount(new LambdaQueryWrapper<SysLogLastPageEntity>()
                    .eq(StringUtils.isNotBlank(i.getCommandId()), SysLogLastPageEntity::getCommandId, i.getCommandId()));
            i.setIsErrurl(integer == 0 ? false : true);

            // 设置bankreferenceno的值
            if (i.getTpiId() == null) {
                i.setBankReferenceNo(null);
            }
            // 设置Message的值
            i.setMessage(i.getMessage() + "\\nCheck: " + i.getCreatedMan() + "\\nRetry: " + i.getUpdateMan());
            return i;
        }).collect(Collectors.toList());
        map.put("FX110", PageUtils.getPage(1, rp, sysFxOrderByIdChildRespList));
        return ApiResp.sucess(map);
    }


    /**
     * @param sysFxOrderLogEntities   子下发操作表集合
     * @param sysFxOrderByIdResp      下发返回类
     * @param sysFxOrderByIdChildResp 子下发返回类
     * @param loginUserName           登陆用户名
     * @return boolean
     */
    public boolean getRetryButtonStatus(List<SysFxOrderLogEntity> sysFxOrderLogEntities, SysFxOrderByIdResp sysFxOrderByIdResp, SysFxOrderByIdChildResp sysFxOrderByIdChildResp, String loginUserName) {

        //  检查当前是否登录，未登录返回false
        if (loginUserName == null) {
            return false;
        } else {
            //  retryReady==true
            boolean retryReady = sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_MANUAL_PROCESS && sysFxOrderByIdChildResp.getIsPressButton() == 0 && sysFxOrderByIdChildResp.getRetryTimes() < 2 && sysFxOrderByIdChildResp.getAction() == null && (sysFxOrderByIdResp.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderByIdResp.getStatus() == FxConstant.STATUS_PROCESSING);
            // 子下发操作log类型为0时created_man！=当前登录用户
            boolean flag1 = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 0 && !item.getCreator().equals(loginUserName)).count() > 0;
            // 子下发操作log卡类型为1的数据不存在
            boolean flag2 = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 1).count() == 0;
            // 三个条件都满足才为true
            return retryReady && flag1 && flag2;
        }
    }

    /**
     * @param sysFxOrderLogEntities   子下发操作表集合
     * @param sysFxOrderByIdResp      下发返回类
     * @param sysFxOrderByIdChildResp 子下发返回类
     * @param loginUserName           登陆用户名
     * @return 0: 可按, 1: 已按(disabled), 2: 不顯示
     */
    public Integer getCheckButtonStatus(List<SysFxOrderLogEntity> sysFxOrderLogEntities, SysFxOrderByIdResp sysFxOrderByIdResp, SysFxOrderByIdChildResp sysFxOrderByIdChildResp, String loginUserName) {
        // (子下发状态为4，is_press_button=0，,retry_times < 2,action === null，父下发状态在（1，2）)==false时时返回2（优先级最高）
        boolean retryReady = sysFxOrderByIdChildResp.getStatus() == 4 && sysFxOrderByIdChildResp.getIsPressButton() == 0 && sysFxOrderByIdChildResp.getRetryTimes() < 2 && sysFxOrderByIdChildResp.getAction() == null && (sysFxOrderByIdResp.getStatus() == 1 || sysFxOrderByIdResp.getStatus() == 2);
        if (!retryReady) {
            return 2;
        } else {
            // 获取子下发操作log的type=2的第一个created_man和登录用户名对比
            String creator = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 2).findFirst().map(SysFxOrderLogEntity::getCreator).orElse(null);
            if (StringUtils.isEmpty(creator)) {
                return 0;
            } else if (StringUtils.isNotBlank(creator) && creator.equals(loginUserName)) {
                return 1;
            } else {
                return 2;
            }
        }
    }





    /**
     * 获取isRunmon数据
     *
     * @param sysFxOrderByIdChildResp
     * @return
     */
    private Boolean getIsRunMonStatus(SysFxOrderByIdChildResp sysFxOrderByIdChildResp) {
        //   'is_runMon' => $row->is_entry === FX110::1 ? false : $row->is_runmon,
        //  子下发is_entry状态为1时IsRunMon=false，否则判断isRunMon
        if (sysFxOrderByIdChildResp.getIsEntry() != null && sysFxOrderByIdChildResp.getIsEntry() != 1) {
            if (sysFxOrderByIdChildResp.getTpiId() != null && sysFxOrderByIdChildResp.getTpiId() > 0) {
                if ((sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_PROCESSING || sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_MANUAL_PROCESS) && getDateDiff(sysFxOrderByIdChildResp.getCreatedAt()) >= 60) {
                    return true;
                }
                if ((sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderByIdChildResp.getStatus() == FxConstant.STATUS_PROCESSING) && getDateDiff(sysFxOrderByIdChildResp.getCreatedAt()) >= 900) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 下发完成按钮
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public ApiResp done(Long id) {

        // 获取下发数据
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(id);

        if (fxOrderEntity == null) {
            throw new ParamException("找不到下发数据", "404");
        }

        // 获取子下发数据
        List<SysFxOrderChildEntity> sysFxOrderChildEntities = sysFxOrderChildMapper.selectList(new LambdaQueryWrapper<SysFxOrderChildEntity>().eq(SysFxOrderChildEntity::getFxOrderMainId, fxOrderEntity.getId()));

        // 检查是否满足完成条件
        if (!getIsDoneClickableAttribute(fxOrderEntity, sysFxOrderChildEntities)) {
            throw new ParamException("不满足完成条件", "500");
        }
        // 检查下发和子下发金额是否正确
        BigDecimal sum = sysFxOrderChildEntities.stream().filter(item -> item.getStatus() == FxConstant.STATUS_COMPLETED).map(SysFxOrderChildEntity::getPaidAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (sum != fxOrderEntity.getPaidAmount()) {
            throw new ParamException("金额不正确", "500");
        }
        // 根据下发数据获取商户信息再获取商户钱包数据
        SysMerchantInfo sysMerchantInfo = sysMerchantInfoMapper.selectById(fxOrderEntity.getMerchantId());
        // 获取第一个商户钱包数据
        SysMerchantWalletEntity sysMerchantWalletEntity = sysMerchantWalletMapper.selectList(new LambdaQueryWrapper<SysMerchantWalletEntity>()
                .eq(SysMerchantWalletEntity::getMerchantId, fxOrderEntity.getMerchantId())).stream().findFirst().orElse(null);

        // 商户钱包余额和冻结资金处理
        fundHoldBalanceMainDone(fxOrderEntity, sysMerchantWalletEntity);

        // 更新下发数据
        fxOrderEntity.setStatus(FxConstant.STATUS_COMPLETED);
        fxOrderEntity.setMerchantWalletBalance(sysMerchantWalletEntity.getBalance());
        fxOrderEntity.setCompletedAt(new Date());
        BigDecimal reduce = sysFxOrderChildEntities.stream().filter(item -> item.getStatus() == FxConstant.STATUS_COMPLETED).map(SysFxOrderChildEntity::getBankFee).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        fxOrderEntity.setUpdatedMan(userName);
        fxOrderEntity.setUpdatedAt(new Date());
        fxOrderEntity.setBankFee(reduce);
        sysFxOrderEntityMapper.updateById(fxOrderEntity);

        // 通过id查询返回类信息
        SysFxOrderEntityResp sysFxOrder = sysFxOrderEntityMapper.getSysFxOrder(id);

        // 处理返回类数据
        SysFxOrderEntityResp sysFxOrderEntityResp = checkSysFxOrderEntityResp(sysFxOrder);

        return ApiResp.sucess(sysFxOrderEntityResp);
    }

    /**
     * 批准按钮
     *
     * @param id
     * @param sysFxOrderBatchReq
     * @return
     */
    @Override
    @Transactional
    public ApiResp batch(Long id, SysFxOrderBatchReq sysFxOrderBatchReq) {

        // 通过下发id查询下发数据
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(id);

        if (fxOrderEntity == null) {
            throw new ParamException("找不到下发数据", "500");
        }
        // 判断下发数据是否是待处理状态
        if (fxOrderEntity.getStatus() != FxConstant.STATUS_PROCESSING) {
            throw new BusinessException("下发数据不是待处理状态");
        }
        // 更新下发数据
        fxOrderEntity.setApproveType(1);
        fxOrderEntity.setApproveTime(new Date());
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        fxOrderEntity.setApprovePerson(userName);
        fxOrderEntity.setStatus(FxConstant.STATUS_PROCESSING);
        sysFxOrderEntityMapper.updateById(fxOrderEntity);

        // 根据条件执行更新操作
        List<DataRow> dataRow = sysFxOrderBatchReq.getDataRow();
        dataRow.stream().map(item -> {

            if (item.getBcId() != null) {
                // 查询银行卡数据
                SysBankCardEntity sysBankCardEntity = sysBankCardMapper.selectById(item.getBcId());
                sysBankCardEntity.setInitBalance(sysBankCardEntity.getInitBalance().add(item.getAmount()));
                sysBankCardEntity.setDayStreamOutMax(sysBankCardEntity.getDayStreamOutMax().add(item.getAmount()));
                sysBankCardEntity.setMonthStreamOutMax(sysBankCardEntity.getMonthStreamOutMax().add(item.getAmount()));
                sysBankCardEntity.setMonthThresholdMax(sysBankCardEntity.getMonthThresholdMax() + 1);
                sysBankCardEntity.setDayThresholdMax(sysBankCardEntity.getDayThresholdMax() + 1);
                // 更新银行卡数据
                sysBankCardMapper.updateById(sysBankCardEntity);
            } else {
                // 获取 'txn_mode' 对应的 TPI 配置
                List<SysThirdPartySettingEntity> sysThirdPartySettingEntities = sysThirdPartySettingMapper.selectList(new LambdaQueryWrapper<SysThirdPartySettingEntity>()
                        .eq(SysThirdPartySettingEntity::getTxnMode, item.getTxnMode())
                        .eq(SysThirdPartySettingEntity::getTradeType, 4));
                SysThirdPartySettingEntity sysThirdPartySettingEntity = sysThirdPartySettingEntities.stream().findFirst().orElse(null);

                // 检查金额范围限制
                if (item.getAmount().compareTo(sysThirdPartySettingEntity.getTradeMin()) < 0 || item.getAmount().compareTo(sysThirdPartySettingEntity.getTradeMax()) > 0) {
                    throw new BusinessException("单笔金额超出范围");
                }

                // 获取第三方支付对象
                SysThirdPartyConfigEntity sysThirdPartyConfigEntity = sysThirdPartyConfigMapper.selectById(sysThirdPartySettingEntity.getThirdPartyConfigId());

                // 进行 TPI 服务检查
                if (sysThirdPartyConfigEntity == null) {
                    SysMerchantInfo sysMerchantInfo = sysMerchantInfoMapper.selectById(fxOrderEntity.getMerchantId());
                    List<SysThirdPartySettingEntity> sysThirdPartySettingEntities1 = sysThirdPartySettingMapper.selectList(new LambdaQueryWrapper<SysThirdPartySettingEntity>()
                            .eq(SysThirdPartySettingEntity::getMerchantId, sysMerchantInfo.getId())
                            .eq(SysThirdPartySettingEntity::getType, 4)
                            .eq(SysThirdPartySettingEntity::getTxnMode, item.getTxnMode()));
                    SysThirdPartySettingEntity sysThirdPartySettingEntity1 = sysThirdPartySettingEntities1.stream().findFirst().orElse(null);
                    if (sysThirdPartySettingEntity1 == null || sysThirdPartySettingEntity1.getStatus() != 1) {
                        throw new BusinessException("未配置 TPI 服务");
                    }
                }
            }
            return item;
        });


        // 通过id查询返回类信息
        SysFxOrderEntityResp sysFxOrder = sysFxOrderEntityMapper.getSysFxOrder(id);

        // 处理返回类数据
        SysFxOrderEntityResp sysFxOrderEntityResp = checkSysFxOrderEntityResp(sysFxOrder);

        return ApiResp.sucess(sysFxOrderEntityResp);
    }

    /**
     * 拒绝按钮
     *
     * @param id
     * @return
     */
    @Override
    public ApiResp reject(Long id) {

        // 通过id获取下发数据
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(id);

        // 查询所有子下发数据
        List<SysFxOrderChildEntity> sysFxOrderChildEntities = sysFxOrderChildMapper.selectList(new LambdaQueryWrapper<SysFxOrderChildEntity>().eq(SysFxOrderChildEntity::getFxOrderMainId, fxOrderEntity.getId()));

        // 判断数据是否可以进行拒绝处理
        if (checkReject(fxOrderEntity, sysFxOrderChildEntities)) {
            return ApiResp.error("不能进行拒绝处理", "500");
        }

        if (fxOrderEntity.getStatus() != FxConstant.STATUS_PENDING) {
            sysFxOrderChildEntities.stream().filter(item -> item.getStatus() != FxConstant.STATUS_FAILED).forEach(item -> {
                if (item.getStatus() == FxConstant.STATUS_PENDING || item.getStatus() == FxConstant.STATUS_PROCESSING) {
                    // 失败, 流水扣回(尚未考虑帐号冻结问题).
                    processFails(item);
                }
                // 将子下发状态设置为失败
                item.setStatus(FxConstant.STATUS_FAILED);
                sysFxOrderChildMapper.updateById(item);
            });
        }
        // 更新下发数据
        fxOrderEntity.setStatus(FxConstant.STATUS_FAILED);
        fxOrderEntity.setCreatedAt(new Date());
        sysFxOrderEntityMapper.updateById(fxOrderEntity);

        if (fxOrderEntity.getStatus()==FxConstant.STATUS_FAILED){
            // 更新商户钱包信息
            SysMerchantWalletEntity sysMerchantWalletEntity = sysMerchantWalletMapper.selectList(new LambdaQueryWrapper<SysMerchantWalletEntity>().eq(SysMerchantWalletEntity::getMerchantId, fxOrderEntity.getMerchantId())).stream().findFirst().orElse(null);
            BigDecimal amount=fxOrderEntity.getRequestAmount().add(fxOrderEntity.getRate());
            sysMerchantWalletEntity.setAvailableBalance(sysMerchantWalletEntity.getAvailableBalance().add(amount));
            sysMerchantWalletEntity.setFreezeBalance(sysMerchantWalletEntity.getFreezeBalance().subtract(amount));
            sysMerchantWalletEntity.setFreezeAmountMain(sysMerchantWalletEntity.getFreezeAmountMain().subtract(amount).compareTo(BigDecimal.ZERO)<0?BigDecimal.ZERO:sysMerchantWalletEntity.getFreezeAmountMain().subtract(amount));
            sysMerchantWalletMapper.updateById(sysMerchantWalletEntity);
        }

        // 通过id查询返回类信息
        SysFxOrderEntityResp sysFxOrder = sysFxOrderEntityMapper.getSysFxOrder(id);

        // 处理返回类数据
        SysFxOrderEntityResp sysFxOrderEntityResp = checkSysFxOrderEntityResp(sysFxOrder);

        return ApiResp.sucess(sysFxOrderEntityResp);
    }

    /**
     * 失败, 流水扣回(尚未考虑帐号冻结问题).
     * processFails
     */
    public void processFails(SysFxOrderChildEntity sysFxOrderChildEntity) {
        SysBankCardFlowEntity sysBankCardFlowEntity = sysBankCardFlowEntityMapper.selectOne(new LambdaQueryWrapper<SysBankCardFlowEntity>().eq(SysBankCardFlowEntity::getBankCardId, sysFxOrderChildEntity.getFromBankCardId()));
        sysBankCardFlowEntity.setFxFreezeAmount(sysBankCardFlowEntity.getFxFreezeAmount().subtract(sysFxOrderChildEntity.getRequestAmount()));
        // 判断交易时间是否是当天
        if (new Date().getDay() == sysFxOrderChildEntity.getUpdatedAt().getDay()) {
            sysBankCardFlowEntity.setDayFlowOut(sysBankCardFlowEntity.getDayFlowOut().subtract(sysFxOrderChildEntity.getRequestAmount()));
        }
        // 判断交易时间是否是当月
        if (new Date().getMonth() == sysFxOrderChildEntity.getUpdatedAt().getMonth()) {
            sysBankCardFlowEntity.setMonthFlowOut(sysBankCardFlowEntity.getMonthFlowOut().subtract(sysFxOrderChildEntity.getRequestAmount()));
            sysBankCardFlowEntity.setMonthSuccessOutCount(sysBankCardFlowEntity.getMonthFreezeSuccessOutCount()<1?0:sysBankCardFlowEntity.getMonthSuccessInCount()-1);
        }
        sysBankCardFlowEntity.setDaySuccessOutCount(sysBankCardFlowEntity.getDaySuccessOutCount()<1?0:sysBankCardFlowEntity.getDaySuccessOutCount()-1);
        // 更新数据
        sysBankCardFlowEntityMapper.updateById(sysBankCardFlowEntity);
    }

    /**
     * 判断是否能进行拒绝处理
     *
     * @param fxOrderEntity
     * @return
     */
    public boolean checkReject(SysFxOrderEntity fxOrderEntity, List<SysFxOrderChildEntity> sysFxOrderChildEntities) {

        if (fxOrderEntity.getStatus() == FxConstant.STATUS_PENDING || (fxOrderEntity.getStatus() == FxConstant.STATUS_MANUAL_PROCESS && sysFxOrderChildEntities.size() == 0)) {
            return true;
        } else if (fxOrderEntity.getStatus() == FxConstant.STATUS_FAILED) {
            return false;
        } else if (true) {
            return fxOrderEntity.getStatus() == FxConstant.STATUS_PENDING && sysFxOrderChildEntities.stream().allMatch(item -> item.getStatus() == FxConstant.STATUS_PENDING)
                    || fxOrderEntity.getStatus() == FxConstant.STATUS_PROCESSING && sysFxOrderChildEntities.stream().allMatch(item -> item.getStatus() == FxConstant.STATUS_FAILED);
        }
        return false;
    }

    /**
     * 判断是否可以点击完成按钮
     *
     * @param fxOrderEntity
     * @return
     */
    public boolean getIsDoneClickableAttribute(SysFxOrderEntity fxOrderEntity, List<SysFxOrderChildEntity> sysFxOrderChildEntities) {
        if (sysFxOrderChildEntities == null || sysFxOrderChildEntities.size() == 0) {
            return false;
        }
        return fxOrderEntity.getStatus() == FxConstant.STATUS_PROCESSING && sysFxOrderChildEntities.stream().allMatch(item -> item.getStatus() != FxConstant.STATUS_PENDING && item.getStatus() != FxConstant.STATUS_PROCESSING & item.getStatus() != FxConstant.STATUS_MANUAL_PROCESS) && sysFxOrderChildEntities.stream().anyMatch(item -> item.getStatus() == FxConstant.STATUS_COMPLETED);
    }

    /**
     * 商户钱包余额和冻结资金处理
     *
     * @param fxOrderEntity
     * @param sysMerchantWalletEntity
     */
    @Transactional
    public void fundHoldBalanceMainDone(SysFxOrderEntity fxOrderEntity, SysMerchantWalletEntity sysMerchantWalletEntity) {

        // 更新商户钱包金额 balance
        sysMerchantWalletEntity.setBalance(sysMerchantWalletEntity.getBalance().subtract(fxOrderEntity.getPaidAmount()));

        // 更新商户钱包可用金额 available_balance
        BigDecimal subtract = fxOrderEntity.getRequestAmount().subtract(fxOrderEntity.getPaidAmount());
        if (subtract.compareTo(BigDecimal.ZERO) > 0) {
            sysMerchantWalletEntity.setAvailableBalance(sysMerchantWalletEntity.getAvailableBalance().subtract(subtract));
        }

        // 更新freeze_amount_main
        BigDecimal subtractAmount = fxOrderEntity.getRequestAmount().subtract(fxOrderEntity.getRate());
        BigDecimal subtractAmountFree = sysMerchantWalletEntity.getFreezeAmountMain().subtract(subtractAmount);
        sysMerchantWalletEntity.setFreezeAmountMain(subtractAmountFree.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : subtractAmountFree);

        // 更新freeze_balance
        BigDecimal subtractAmount2 = fxOrderEntity.getRequestAmount().subtract(fxOrderEntity.getRate());
        BigDecimal subtractAmountFree2 = sysMerchantWalletEntity.getFreezeBalance().subtract(subtractAmount2);
        sysMerchantWalletEntity.setFreezeBalance(subtractAmountFree2.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : subtractAmountFree2);

        // 保存数据
        sysMerchantWalletMapper.updateById(sysMerchantWalletEntity);
    }

    /**
     * 根据tx_mode属性找到第三方支付方式
     */
    private String getThirdPartyPaymentMethod(Integer txnMode) {
        // TODO:待完成
        if (txnMode >= 101 && txnMode <= 199) {
            // VNPAY
            return "VNPAY";
        } else if (txnMode >= 201 && txnMode <= 299) {
            // Dapay
            return "Dapay";
        } else if (txnMode >= 301 && txnMode <= 399) {
            // 8Pay
            return "8Pay";
        } else if (txnMode >= 401 && txnMode <= 499) {
            // QijiPay
            return "QijiPay";
        } else if (txnMode >= 501 && txnMode <= 599) {
            // H1Pay
            return "H1Pay";
        } else if (txnMode >= 601 && txnMode <= 699) {
            // YouktPay
            return "YouktPay";
        }
        throw new BusinessException("找不到对应第三方支付方式");
    }

    /**
     * 计算时间差值（以秒为单位）
     *
     * @return
     */
    private long getDateDiff(Date date) {

        return (new Date().getTime() - date.getTime()) / 1000;
    }

    /**
     * 为excel表格封装数据
     *
     * @param sysFxOrderList
     * @return
     */
    private List<SysFxOrderExcelModel> addDateForExcel(List<SysFxOrderEntityResp> sysFxOrderList) {
        return sysFxOrderList.stream().map(item -> {
            SysFxOrderExcelModel sysFxOrderExcelModel = new SysFxOrderExcelModel();
            sysFxOrderExcelModel.setId(item.getAltId());
            sysFxOrderExcelModel.setMerchantCode(item.getShCode());
            sysFxOrderExcelModel.setBank(item.getToBank());
            sysFxOrderExcelModel.setBeneficiaryName(item.getToMan());
            sysFxOrderExcelModel.setAccountNumber(item.getToCardNumber());
            sysFxOrderExcelModel.setReqAmt(item.getRequestAmount());
            sysFxOrderExcelModel.setFee(item.getBankFee());
            sysFxOrderExcelModel.setPayoutAmt(item.getPaidAmount());
            sysFxOrderExcelModel.setInfo("Note/备注: \n" +
                    "Transaction Code/交易代码: 3" + item.getTrCode());
            sysFxOrderExcelModel.setStatus("Processing/" + getSysFxOrderStatusNote(item.getStatus()));
            sysFxOrderExcelModel.setCreatedBy(item.getCreatedMan());
            sysFxOrderExcelModel.setUpdated(item.getUpdatedAt());
            sysFxOrderExcelModel.setCreated(item.getCreatedAt());
            sysFxOrderExcelModel.setUpdateBy(item.getUpdatedMan());
            return sysFxOrderExcelModel;
        }).collect(Collectors.toList());
    }

    /**
     * 根据子下发状态判断下发状态(数字)
     */
    public Integer getSysFxOrderStatus(List<SysFxOrderChildEntity> childEntities) {
        List<Integer> list = new ArrayList<>();
        for (SysFxOrderChildEntity childEntity : childEntities) {
            // 遍历子下发并获取状态并添加到集合中
            list.add(childEntity.getStatus());
        }
        // 子下发有一个为5，父下发为5
        if (list.contains(FxConstant.STATUS_FAILED)) {
            return FxConstant.STATUS_FAILED;
        }
        // 子下发全为4，父下发为4
        if (list.stream().allMatch(item -> item == FxConstant.STATUS_MANUAL_PROCESS)) {
            return FxConstant.STATUS_MANUAL_PROCESS;
        }
        // 子下发全为3，父下发为3
        if (list.stream().allMatch(item -> item == FxConstant.STATUS_COMPLETED)) {
            return FxConstant.STATUS_COMPLETED;
        }
        // 子下发全为1，父下发为1
        if (list.stream().allMatch(item -> item == FxConstant.STATUS_PENDING)) {
            return FxConstant.STATUS_PENDING;
        }
        // 其他情况父下发为2
        return FxConstant.STATUS_PROCESSING;
    }

    /**
     * 根据子下发状态判断下发状态(中文注释)
     */
    public String getSysFxOrderStatusNote(Integer status) {
        switch (status) {
            case 1:
                return "Pending–等待机器人跑";
            case 2:
                return "Processing–机器人正在跑";
            case 3:
                return "Completed–成功交易";
            case 4:
                return "Manual process–失败后的手动操作,人工可操作成成功或失败(如果交易试成功的)";
            default:
                return "Failed–失败, 不可更改状态 BS200";
        }
    }

}




